package fast.calc.rogue;

import fast.calc.AttackType;
import fast.calc.Attacks;
import fast.calc.AttacksBlock;
import fast.calc.Stats;
import fast.calc.WeaponStats;
import fast.data.Spec;
import fast.data.Stat;
import fast.data.WeaponType;

public class AttacksRogue extends Attacks {
	
	double spellScaling90 = 1246.298583984375000;

	public AttacksRogue(FastRogue f){
		super(f);
		spellScaling = spellScaling90;
	}
	
	public AttacksBlock get_dmg_sinister_strike(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 1.45;
		double base_damage = 0.1780000031 * spellScaling;
		damage = (damage + base_damage) * mod;
		if(s.getGearBuffs().hasSet("t14_2pc")){
			damage *= 1.15;
		}
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("sinister_strike",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_sinister_strike(){
		double crit_chance = get_crit_mh();
		return crit_chance;
	}
	
	public AttacksBlock get_dmg_main_gauche(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 1.2;
		damage *= mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("main_gauche",AttackType.physical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_eviscerate(){
		return get_dmg_eviscerate(5);
	}
	
	public AttacksBlock get_dmg_eviscerate(int cps){
		double avg = 0.5929999948 * spellScaling;
		double min = avg * ( 1 - 1.0 / 2);
		double max = avg * ( 1 + 1.0 / 2);
		double bonus_damage = 0.7860000134 * spellScaling;
		
		double damage = ((min+max)/2 + (bonus_damage + (s.getBuffed(Stat.ap) * 0.16)) * cps);
		if(s.getSpec() == Spec.Combat)
			damage *= 1.35;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("eviscerate",AttackType.physical,damage, crit_damage);
	}
		
	public AttacksBlock get_dmg_instant_poison(){
		double base_damage = 0.3129999936 * spellScaling;
		double damage = base_damage + 0.109 * s.getBuffed(Stat.ap);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("instant_poison",AttackType.magical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_deadly_poison(){
		double base_damage = 0.6000000238 * spellScaling;
		double damage = base_damage + 0.213 * s.getBuffed(Stat.ap);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("deadly_poison",AttackType.magical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_wound_poison(){
		double base_damage = 0.3129999936 * spellScaling;
		double damage = base_damage + 0.09 * s.getBuffed(Stat.ap);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("wound_poison",AttackType.magical,damage, crit_damage);
	}
	
	public double get_crit_main_gauche(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_revealing_strike(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		damage *= 1.25;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("revealing_strike",AttackType.physical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_ks_mh(){
		Stats s = f.getStats();
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		damage *= 1.5;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("ks_mh",AttackType.physical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_ks_oh(){
		Stats s = f.getStats();
		WeaponStats w = s.getOh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 0.5;
		if(s.getSpec() == Spec.Combat)
			mod = 0.875;
		damage *= mod;
		damage *= 1.5;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("ks_oh",AttackType.physical,damage, crit_damage);
	}
	
	public double get_crit_ks_mh(){
		return get_crit_mh();
	}
	
	public double get_crit_ks_oh(){
		return get_crit_oh();
	}
	
	public AttacksBlock get_dmg_mh(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("mh",AttackType.physical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_oh(){
		WeaponStats w = s.getOh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double mod = 0.5;
		if(s.getSpec() == Spec.Combat)
			mod = 0.875;
		damage *= mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("oh",AttackType.physical,damage, crit_damage);
	}
	
	public double get_crit_mh(){
		double crit_chance = s.getCritPercent();
		return crit_chance;
	}
	
	public double get_crit_oh(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_sb_mh(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("sb_mh",AttackType.magical,damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_sb_oh(){
		WeaponStats w = s.getOh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double mod = 0.5;
		if(s.getSpec() == Spec.Combat)
			mod = 0.875;
		damage *= mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("sb_oh",AttackType.magical,damage, crit_damage);
	}
	
	public double get_crit_sb_mh(){
		return get_crit_mh();
	}
	
	public double get_crit_sb_oh(){
		return get_crit_oh();
	}
	
	public double get_crit_eviscerate(){
		return get_crit_mh();
	}
	
	public double get_crit_revealing_strike(){
		return get_crit_mh();
	}
	
	public double get_crit_instant_poison(){
		return get_crit_mh();
	}
	
	public double get_crit_deadly_poison(){
		return get_crit_instant_poison();
	}
	
	public double get_crit_wound_poison(){
		return get_crit_instant_poison();
	}
	
	public AttacksBlock get_dmg_envenom(){
		return get_dmg_envenom(5);
	}
	
	public AttacksBlock get_dmg_envenom(int cps){
		double base_damage = 0.3849999905 * spellScaling;
		double damage = (base_damage + s.getBuffed(Stat.ap) * 0.112) * cps;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("envenom",AttackType.magical,damage, crit_damage);
	}
	
	public double get_crit_envenom(){
		return get_crit_instant_poison();
	}
	
	public AttacksBlock get_dmg_rupture(){
		return get_dmg_rupture(5);
	}
	
	public AttacksBlock get_dmg_rupture(int cp){
		double base_damage = 0.1850000024 * spellScaling;
		double bonus_damage = 0.0260000005 * spellScaling;
		
		double[] ap_scaling = {0.0,0.025,0.04,0.05,0.056, 0.062}; 
		
		double damage = base_damage + bonus_damage * cp + ap_scaling[cp] * s.getBuffed(Stat.ap);
		if(s.getSpec() == Spec.Subtlety)
			damage *= 1.5;
		if(s.getSpec() == Spec.Combat)
			damage *= 1.35;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("rupture",AttackType.bleed, damage, crit_damage);
	}
	
	public double get_crit_rupture(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_venomous_wound(){
		double base_damage = 0.5500000119 * spellScaling;
		double damage = base_damage + 0.1600000 * s.getBuffed(Stat.ap);
		if(s.getGearBuffs().hasSet("t14_2pc"))
			damage *= 1.20;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("venomous_wound",AttackType.magical, damage, crit_damage);
	}
	
	public double get_crit_venomous_wound(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_mutilate_mh(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 2.0;
		double bonus_damage = 0.1790000051 * spellScaling;
		damage = (damage + bonus_damage) * mod;
		if(w.getType() != WeaponType.dagger)
			damage = 0.0;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("mutilate_mh",AttackType.physical, damage, crit_damage);
	}
	
	public AttacksBlock get_dmg_mutilate_oh(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 2.0;
		mod *= 0.5; // offhand penalty
		double base_damage = 0.1790000051 * spellScaling;
		damage = (damage + base_damage) * mod;
		if(w.getType() != WeaponType.dagger)
			damage = 0.0;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("mutilate_oh",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_mutilate_mh(){
		double crit_chance = get_crit_mh();
		return crit_chance;
	}
	
	public double get_crit_mutilate_oh(){
		double crit_chance = get_crit_oh();
		return crit_chance;
	}
	
	public AttacksBlock get_dmg_dispatch(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 4.6;
		double base_damage = 0.4490000010 * spellScaling;
		damage = (damage + base_damage) * mod;
		if(w.getType() != WeaponType.dagger)
			damage = 0.0;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("dispatch",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_dispatch(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_hemorrhage(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 1.4;
		if(w.getType() == WeaponType.dagger)
			mod = 2.03;
		damage = damage * mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("hemorrhage",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_hemorrhage(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_hemorrhage_dot(){
		AttacksBlock hemo_direct = get_dmg_hemorrhage();
		double hemo_direct_crit_chance = get_crit_hemorrhage();
		double hit = hemo_direct.getHitDamage() * ( 1 - hemo_direct_crit_chance);
		double crit = hemo_direct.getCritDamage() * hemo_direct_crit_chance;
		
		double damage = (hit + crit) / 8;
		double mod = 0.5;
		damage = damage * mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("hemorrhage_dot",AttackType.bleed, damage, crit_damage);
	}
	
	public double get_crit_hemorrhage_dot(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_backstab(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 2.75;
		double base_damage = 0.3070000112 * spellScaling;
		damage = (damage + base_damage) * mod;
		if(s.getGearBuffs().hasSet("t14_2pc"))
			damage *= 1.10;
		if(w.getType() != WeaponType.dagger)
			damage = 0.0;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("backstab",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_backstab(){
		double crit_chance = get_crit_mh();
		return crit_chance;
	}
	
	public AttacksBlock get_dmg_ambush(){
		WeaponStats w = s.getMh();
		double damage = w.getSpeed() * w.getDps() + w.getNormalizedSpeed() * s.getBuffed(Stat.ap) / 14.;
		double mod = 3.25;
		double base_damage = 0.5000000000 * spellScaling;
		if(w.getType() == WeaponType.dagger)
			mod *= 1.447;
		damage = (damage + base_damage) * mod;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("ambush",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_ambush(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_st(){
		double damage = 1 + 0.3 * s.getBuffed(Stat.ap);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("st",AttackType.physical, damage, crit_damage);
	}
	
	public double get_crit_st(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_st_mh(){
		WeaponStats w = s.getMh();
		double damage = 0.75 * w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("st_mh",AttackType.magical,damage, crit_damage);
	}
	
	public double get_crit_st_mh(){
		return get_crit_mh();
	}
	
	public AttacksBlock get_dmg_st_oh(){
		WeaponStats w = s.getOh();
		double damage = w.getSpeed() * ( w.getDps() + s.getBuffed(Stat.ap) / 14.);
		double mod = 0.5;
		if(s.getSpec() == Spec.Combat)
			mod = 0.875;
		damage *= mod;
		damage *= 0.75;
		double crit_damage = damage * s.getCritMultiplier();
		return new AttacksBlock("st_oh",AttackType.magical,damage, crit_damage);
	}
	
	public double get_crit_st_oh(){
		return get_crit_oh();
	}
}

